package com.micai.boss.weixin.repository;

import com.alibaba.fastjson.JSON;
import com.micai.boss.base.constant.ErrorCodeEnum;
import com.micai.boss.base.exception.ServiceException;
import com.micai.boss.redis.service.AbstractRedisService;
import com.micai.boss.weixin.constant.WeiXinConstant;
import com.micai.boss.weixin.entity.AccessToken;
import com.micai.boss.weixin.entity.Ticket;
import com.micai.boss.weixin.util.WeixinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

/**
 * 描述：
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/4/19 11:10
 */
@Repository
public abstract class AbstractWeiXinRepository extends AbstractRedisService {

    private Logger logger = LoggerFactory.getLogger(AbstractWeiXinRepository.class);

    @Value("${weixin.appid}")
    private String app_id;

    @Value("${weixin.appsecret}")
    private String app_secret;

    /**
     * 获取AccountToken
     * @return
     */
    public AccessToken getAccessToken(){
        AccessToken accessToken = null;
        try {
            Object obj = super.get(WeiXinConstant.WX_CACHE_TOKEN_KEY + app_id);
            if (null != obj){
                accessToken = (AccessToken) obj;
                //校验token有效期
                if ((System.currentTimeMillis() - accessToken.getTimestamp())/1000 > (accessToken.getExpiresIn() - 60 * 10)){
                    //同步Token
                    accessToken = this.syncAccessToken();
                }
            }else{
                accessToken = this.syncAccessToken();
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("微信[wx]获取缓存Token异常:{}", e.getMessage());
        }
        return accessToken;
    }

    private synchronized AccessToken syncAccessToken(){
        try{
            AccessToken accessToken = WeixinUtil.getAccessToken(app_id, app_secret);
            logger.debug(JSON.toJSONString(accessToken));
            if (null != accessToken && this.updateAccessToken(accessToken)){
                return accessToken;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        throw new ServiceException(ErrorCodeEnum.系统提醒.getCode(), "同步微信Token失败");
    }

    private Boolean updateAccessToken(AccessToken accessToken){
        try{
            if (null != accessToken){
                super.put(WeiXinConstant.WX_CACHE_TOKEN_KEY + app_id, accessToken,accessToken.getExpiresIn()/60);
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("微信[wx]更新缓存Token异常:{}", e.getMessage());
        }
        return false;
    }

    public Ticket getTicket(){
        Ticket ticket = null;
        try{
            Object obj = super.get(WeiXinConstant.WX_CACHE_TICKET_KEY + app_id);
            if (null != obj){
                ticket = (Ticket) obj;
            }
            if (null == ticket){
                //同步Ticket
                ticket = this.syncTicket();
            }else {
                if ((System.currentTimeMillis() - ticket.getTimestamp())/1000 > (ticket.getExpiresIn() - 60 * 10)){
                    //同步Ticket
                    ticket = this.syncTicket();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("微信[wx]获取缓存Ticket异常:{}", e.getMessage());
        }
        return ticket;
    }

    private synchronized Ticket syncTicket(){
        try{
            AccessToken accessToken = getAccessToken();
            if (null == accessToken){
                throw new ServiceException(ErrorCodeEnum.系统提醒.getCode(), "同步微信Ticket失败[Token为空]");
            }
            Ticket ticket = WeixinUtil.getTicket(accessToken.getToken(),"jsapi");
            logger.debug(JSON.toJSONString(ticket));
            if (null != ticket && this.updateTicket(ticket)){
                return ticket;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        throw new ServiceException(ErrorCodeEnum.系统提醒.getCode(), "同步微信Ticket失败");
    }

    private Boolean updateTicket(Ticket ticket){
        try{
            if (null != ticket){
                super.put(WeiXinConstant.WX_CACHE_TICKET_KEY + app_id, ticket,ticket.getExpiresIn()/60);
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("微信[wx]更新缓存Ticket异常:{}", e.getMessage());
        }
        return false;
    }

}
